package com.ruoyi.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.system.domain.DesignBase;
import com.ruoyi.system.domain.DesignScheme;
import com.ruoyi.system.domain.OperationLog;
import com.ruoyi.system.dto.design.DesignQueryDTO;
import com.ruoyi.system.dto.design.ModifyDesignDto;
import com.ruoyi.system.enums.BusinessTypeEnum;
import com.ruoyi.system.enums.OperateActionEnum;
import com.ruoyi.system.enums.SpaceTypeEnum;
import com.ruoyi.system.mapper.DesignBaseMapper;
import com.ruoyi.system.service.DesignBaseService;
import com.ruoyi.system.service.DesignSchemeService;
import com.ruoyi.system.utils.OperationLogUtils;
import com.ruoyi.system.vo.design.DesignProjectVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 基础设计表Service实现类
 */
@Service
public class DesignBaseServiceImpl extends ServiceImpl<DesignBaseMapper, DesignBase> implements DesignBaseService {

    @Autowired
    private StringRedisTemplate redisTemplate;


    @Resource
    private DesignBaseMapper designBaseMapper;


    @Autowired
    private DesignSchemeService designSchemeService;

    private static final String REDIS_KEY_PREFIX = "design_base_id_seq:";

    public String generateId() {
        LocalDate currentDate = LocalDate.now();
        String key = REDIS_KEY_PREFIX + currentDate.format(DateTimeFormatter.ofPattern("yyyyMMdd"));

        // Redis 原子自增（默认初始值为 0，需手动设置）
        Long sequence = redisTemplate.opsForValue().increment(key);
        if (sequence == null) {
            // 初始化为 1
            redisTemplate.opsForValue().setIfAbsent(key, "1");
            sequence = 1L;
        }

        return String.format("SJ-%s-%03d", currentDate.format(DateTimeFormatter.ofPattern("yyyyMMdd")), sequence);
    }


    @Override
    public IPage<DesignProjectVO> getPageList(DesignQueryDTO query) {
        // DesignBaseMapper.xml
        Page<DesignProjectVO> page = new Page<>(query.getPageNum(), query.getPageSize());
        IPage<DesignProjectVO> designProjectVOIPage = designBaseMapper.selectDesignProjectPageList(page, query);
        List<DesignProjectVO> records = designProjectVOIPage.getRecords();
        List<Long> designIds = records.stream().map(DesignProjectVO::getId).collect(Collectors.toList());
        for (DesignProjectVO designProjectVO : records) {
            List<DesignScheme> designSchemes = designSchemeService.selectByDesignBaseId(designProjectVO.getId());
            if (CollectionUtil.isNotEmpty(designSchemes)) {
                DesignScheme designScheme = designSchemes.get(0);
                String schemeName = designScheme.getSchemeName();
                String panoramaUrl = designScheme.getPanoramaUrl();
                Integer useOnlineDesign = designScheme.getUseOnlineDesign();
                List<SpaceTypeEnum> spaceTypeEnums = designScheme.getImages().stream().map(x -> SpaceTypeEnum.getByValue(x.getSpaceType())).filter(Objects::nonNull).collect(Collectors.toList());
                designProjectVO.setSchemeName(schemeName);
                designProjectVO.setPanoramaUrl(panoramaUrl);
                designProjectVO.setSpaceTypes(spaceTypeEnums);
            }
            OperationLog bestNewLog = OperationLogUtils.getBestNewLog(designProjectVO.getId().toString(), BusinessTypeEnum.DESIGN.getCode(), OperateActionEnum.STATUS_CHANGE.getCode());
            designProjectVO.setStatusRemark(bestNewLog.getRemark());

        }


        return designProjectVOIPage;
    }



    @Override
    public IPage<DesignProjectVO> getPageListNew(DesignQueryDTO queryDTO) {
        // DesignBaseMapper.xml
        // 1. 初始化分页参数（默认pageNum=1，pageSize=20，来自DesignQueryDTO）
        Page<DesignProjectVO> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());

        // 2. 调用Mapper自定义SQL，执行连表分页查询

        // 3. 返回分页结果（VO已在set方法中完成枚举和List转换）
        return baseMapper.selectDesignProjectWithLogPage(page, queryDTO);
    }

    /**
     * 新增设计基础信息（自动生成设计编号）
     */
    @Override
    public boolean saveWithDesignNo(DesignBase designBase) {
        // 生成并设置设计编号
        designBase.setDesignNo(generateId());
        return save(designBase);
    }

    /**
     * 更新设计状态
     */
    @Override
    public boolean updateDesignStatus(Long id, String status) {
        DesignBase designBase = new DesignBase();
        designBase.setId(id);
        designBase.setDesignStatus(status);
        return updateById(designBase);
    }

    /**
     * 更新设计进度
     */
    @Override
    public boolean updateDesignProgress(Long id, Integer progress) {
        // 确保进度在0-100之间
        if (progress < 0) progress = 0;
        if (progress > 100) progress = 100;

        DesignBase designBase = new DesignBase();
        designBase.setId(id);
        designBase.setDesignProgress(progress);
        return updateById(designBase);
    }

    @Override
    @Transactional
    public boolean updateById(DesignBase newDesign) {
        DesignBase oldDesign = baseMapper.selectById(newDesign.getId());
        if (oldDesign == null || oldDesign.getIsDeleted() == 1) {
            throw new ServiceException("设计不存在或已被删除");
        }
        newDesign.setUpdatedTime(LocalDateTime.now());
        newDesign.setCreatedTime(null);
        newDesign.setDesignNo(null);
        baseMapper.updateById(newDesign);
        String remark = null;
        if (newDesign instanceof ModifyDesignDto) {
            ModifyDesignDto designBase1 = (ModifyDesignDto) newDesign;
            remark = designBase1.getRemark();
        }

        // 判断修改状态
        if (newDesign.getDesignStatus() != null && !newDesign.getDesignStatus().equals(oldDesign.getDesignStatus())) {
            OperationLogUtils.recordDesignStatusChange(
                    newDesign.getId(),
                    newDesign.getSchemeName(),
                    oldDesign.getDesignStatus(),
                    newDesign.getDesignStatus(),
                    remark
            );
        }

        // 保存变更日志
        OperationLogUtils.recordDataChange(
                newDesign.getId().toString(),
                newDesign.getSchemeName(),
                BusinessTypeEnum.DESIGN_DATA_CHANGE.getCode(),
                OperateActionEnum.UPDATE_DESIGN.getCode(),
                JSON.toJSONString(oldDesign),
                JSON.toJSONString(newDesign),
                remark
        );


        return true;
    }

}
